<?php

/*
 * Copyright (C) 2006-2009 Pham Cong Dinh
 *
 * This file is part of Pone.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 3 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */

/**
 * A table of data representing a database result set, which is usually generated by
 * executing a statement that queries the database.
 *
 * A ResultSet object maintains a cursor pointing to its current row of data
 * Initially the cursor is positioned before the first row
 *
 * The next method moves the cursor to the next row, and because it returns false when
 * there are no more rows in the ResultSet object, it can be used in a while loop to
 * iterate through the result set
 *
 * @category   spica
 * @package    core
 * @subpackage datasource\db
 * @author     Pham Cong Dinh <pcdinh at phpvietnam dot net>
 * @since      Version 0.1
 * @since      October 22, 2008
 * @copyright  Pham Cong Dinh (http://www.phpvietnam.net)
 * @license    http://www.gnu.org/licenses/lgpl-3.0.txt
 * @version    $Id: ResultSet.php 1488 2009-12-12 18:31:08Z pcdinh $
 */
interface SpicaResultSet
{
    /**
     * Force this database treats mixed case quoted SQL identifiers as case insensitive and stores them in lower case
     */
    const IDENTIFIER_LOWERCASE  = 3000;

    /**
     * Force this database treats mixed case quoted SQL identifiers as case insensitive and stores them in upper case
     */
    const IDENTIFIER_UPPERCASE  = 3001;

    /**
     * Force this database treats mixed case quoted SQL identifiers as case insensitive and stores them in mixed case
     */
    const IDENTIFIER_MIXEDCASE  = 3002;

    /**
     * Returns rows as associative arrays
     */
    const FETCH_ASSOC           = 4000;

    /**
     * Returns rows as arrays where fields are indexed in numbers
     */
    const FETCH_INDEX           = 4001;

    /**
     * Retrieves all rows in the current result set as a <code>SpicaRowList</code> object
     *
     * @return {@link SpicaRowList}
     */
    public function getRowList();

    /**
     * Retrieves XML representation of all rows in the current result set
     *
     * @return string
     */
    public function getXml();

    /**
     * Gets a JSON representation of rows contained in the result set
     *
     * @return string
     */
    public function getJson();

    /**
     * Fetches all rows from the result set as an associative array
     *
     * This method always returns an array. Field names returned by this function are case-sensitive
     *
     * @return array
     */
    public function getAssociativeArray();

    /**
     * Determines how many result rows were found by the preceding query
     *
     * @return int The number of result rows.
     */
    public function rowCount();

    /**
     * Retrieves the current row number
     *
     * The first row is number 1, the second number 2, and so on.
     * <p>
     * <strong>Note:</strong>Support for the <code>getRow</code> method
     * is optional for <code>SpicaResultSet</code>s with a result
     * set type of <code>TYPE_FORWARD_ONLY</code>
     *
     * @throws SpicaDatabaseException if a database access error occurs or this method is called on a closed result set
     * @throws SpicaSQLFeatureNotSupportedException if the SpicaConnection adapters does not support this method
     * @return int the current row number; <code>0</code> if there is no current row
     */
    public function currentRowNumber();

    /**
     * Returns row at the current cursor
     *
     * @see    SpicaResultSet#absolute()
     * @return array
     */
    public function currentRow();

    /**
     * Tests if it is possible to retrieve data from a <code>SpicaResultSet</code> object
     *
     * A <code>SpicaResultSet</code> object is not available to extract data
     * when this object contains an error
     *
     * @return bool
     */
    public function isAvailable();

    /**
     * Retrieves whether this <code>SpicaResultSet</code> object has been closed
     *
     * A <code>SpicaStatement</code> is closed if the method close has been called on it,
     * or if it is automatically closed
     *
     * @return bool true if this <code>SpicaStatement</code> object is closed; false if it is still open
     */
    public function isClosed();

    /**
     * Retrieves whether the cursor is on the first row of
     * this <code>SpicaResultSet</code> object.
     * <p>
     * <strong>Note:</strong>Support for the <code>isFirst</code> method
     * is optional for <code>SpicaResultSet</code>s with a result
     * set type of <code>TYPE_FORWARD_ONLY</code>
     *
     * @return bool <code>true</code> if the cursor is on the first row;
     * <code>false</code> otherwise
     * @throws SpicaDatabaseException if a database access error occurs or this method is
     *            called on a closed result set
     * @throws SpicaSQLFeatureNotSupportedException if the Connection adapter does not support
     * this method
     */
    public function isFirst();

    /**
     * Retrieves whether the cursor is on the last row of
     * this <code>SpicaResultSet</code> object.
     *  <strong>Note:</strong> Calling the method <code>isLast</code> may be expensive
     * because the SpicaConnection adapter
     * might need to fetch ahead one row in order to determine
     * whether the current row is the last row in the result set.
     * <p>
     * <strong>Note:</strong> Support for the <code>isLast</code> method
     * is optional for <code>SpicaResultSet</code>s with a result
     * set type of <code>TYPE_FORWARD_ONLY</code>
     * @return bool <code>true</code> if the cursor is on the last row;
     *              <code>false</code> otherwise
     * @throws SpicaDatabaseException if a database access error occurs or this method is
     *            called on a closed result set
     * @throws SpicaSQLFeatureNotSupportedException if the SpicaConnection adapter does not support
     * this method
     */
    public function isLast();

    /**
     * Moves the cursor to the last row in this <code>SpicaResultSet</code> object
     *
     * @return bool <code>true</code> if the cursor is on a valid row;
     * <code>false</code> if there are no rows in the result set
     * @throws SpicaDatabaseException if a database access error
     * occurs; this method is called on a closed result set
     * or the result set type is <code>TYPE_FORWARD_ONLY</code>
     * @throws SpicaSQLFeatureNotSupportedException if the SpicaConnection adapter does not support
     * this method
     */
    public function last();

    /**
     * Moves the cursor to the given row number in this <code>SpicaResultSet</code> object.
     *
     * <p>If the row number is positive, the cursor moves to the given row number with respect to the
     * beginning of the result set.  The first row is row 1, the second is row 2, and so on.
     *
     * <p>If the given row number is negative, the cursor moves to an absolute row position with respect to
     * the end of the result set.  For example, calling the method <code>absolute(-1)</code> positions the
     * cursor on the last row; calling the method <code>absolute(-2)</code>
     * moves the cursor to the next-to-last row, and so on.
     *
     * <p>An attempt to position the cursor beyond the first/last row in the result set
     * leaves the cursor before the first row or after the last row.
     *
     * <p><B>Note:</B> Calling <code>absolute(1)</code> is the same as calling <code>first()</code>.
     * Calling <code>absolute(-1)</code> is the same as calling <code>last()</code>.
     *
     * @param row the number of the row to which the cursor should move.
     *        A positive number indicates the row number counting from the
     *        beginning of the result set; a negative number indicates the
     *        row number counting from the end of the result set
     * @return <code>true</code> if the cursor is moved to a position in this
     * <code>SpicaResultSet</code> object;
     * <code>false</code> if the cursor is before the first row or after the
     * last row
     * @throws SpicaDatabaseException if a database access error
     * occurs; this method is called on a closed result set
     * or the result set type is <code>TYPE_FORWARD_ONLY</code>
     * @throws SpicaSQLFeatureNotSupportedException if the SpicaConnection adapter does not support
     * this method
     */
    public function absolute($offset);

    /**
     * Moves the cursor to the first row in this <code>SpicaResultSet</code> object.
     *
     * @throws SpicaDatabaseException if a database access error occurs; this method is called on a closed result set
     *         or the result set type is <code>TYPE_FORWARD_ONLY</code>
     * @throws SpicaSQLFeatureNotSupportedException if the SpicaConnection adapter does not support this method
     * @return bool <code>true</code> if the cursor is on a valid row;
     *              <code>false</code> if there are no rows in the result set
     */
    public function first();

    /**
     * Moves the cursor to the previous row in this
     * <code>SpicaResultSet</code> object.
     * <p>
     * When a call to the <code>previous</code> method returns <code>false</code>,
     * the cursor is positioned before the first row.  Any invocation of a
     * <code>SpicaResultSet</code> method which requires a current row will result in a
     * <code>SpicaSQLException</code> being thrown.
     * <p>
     * If an input stream is open for the current row, a call to the method
     * <code>previous</code> will implicitly close it. A <code>SpicaResultSet</code>
     *  object's warning change is cleared when a new row is read.
     * <p>
     *
     * @return bool <code>true</code> if the cursor is now positioned on a valid row;
     *              <code>false</code> if the cursor is positioned before the first row
     * @throws SpicaSQLException if a database access error occurs;
     *         this method is called on a closed result set or the result set type is <code>TYPE_FORWARD_ONLY</code>
     * @throws SpicaSQLFeatureNotSupportedException if the SpicaConnection adapter does not support
     * this method
     */
    public function previous();

    /**
     * Moves the cursor froward one row from its current position.
     * A <code>SpicaResultSet</code> cursor is initially positioned
     * before the first row; the first call to the method
     * <code>next</code> makes the first row the current row; the
     * second call makes the second row the current row, and so on.
     * <p>
     * When a call to the <code>next</code> method returns <code>false</code>,
     * the cursor is positioned after the last row.
     * Any invocation of a <code>SpicaResultSet</code> method which requires a
     * current row will result in a <code>SpicaDatabaseException</code> being thrown.
     *
     * If the result set type is <code>TYPE_FORWARD_ONLY</code>, it is vendor specified
     * whether their database adapter implementation will return <code>false</code>
     * or throw an <code>SpicaDatabaseException</code> on a subsequent call to <code>next</code>.
     *
     * <P>If an input stream is open for the current row, a call
     * to the method <code>next</code> will
     * implicitly close it. A <code>SpicaResultSet</code> object's
     * warning chain is cleared when a new row is read.
     *
     * @return bool <code>true</code> if the new current row is valid;
     *              <code>false</code> if there are no more rows
     * @throws SpicaDatabaseException if a database access error occurs or this method is
     *            called on a closed result set
     */
    public function next();

    /**
     * Releases this <code>SpicaResultSet</code> object's database
     * and resources immediately instead of waiting for
     * this to happen when it is automatically closed
     *
     * <P><B>Note:</B> A <code>SpicaResultSet</code> object
     * is automatically closed by the
     * <code>SpicaStatement</code> object that generated it when
     * that <code>SpicaStatement</code> object is closed,
     * re-executed, or is used to retrieve the next result from a
     * sequence of multiple results.
     */
    public function close();

    /**
     * This method returns data about the columns returned as part of the
     * result set as a <code>SpicaResultSetMetaData</code> instance.
     *
     * @exception SpicaDatabaseException If an error occurs.
     * @return SpicaResultSetMetaData The <code>SpicaResultSetMetaData</code> instance for this result set.
     */
    public function getMetaData();
}

/**
 * The SpicaResultSetMetaData interface creates an object that can be used to find out
 * about the types and properties of the columns in a SpicaResultSet.
 *
 * @category   spica
 * @package    core
 * @subpackage datasource
 * @author     Pham Cong Dinh <pcdinh at phpvietnam dot net>
 * @since      Version 0.3
 * @since      December 13, 2009
 * @copyright  Pham Cong Dinh (http://www.phpvietnam.net)
 * @license    http://www.gnu.org/licenses/lgpl-3.0.txt
 * @version    $Id: ResultSet.php 1488 2009-12-12 18:31:08Z pcdinh $
 */
interface SpicaResultSetMetaData
{
    /**
     * This method returns the number of columns in the result set.
     *
     * @exception SpicaDatabaseException If an error occurs.
     * @return int|false The number of columns in the result set.
     */
    public function getColumnCount();

    /**
     * This method returns the name of the specified column.
     *
     * @exception SpicaDatabaseException If an error occurs.
     * @param  int $column The index of the column to return the name of.
     * @return string|false The name of the column.
     */
    public function getColumnName($column);

    /**
     * This method returns names of columns by order.
     *
     * @exception SpicaDatabaseException If an error occurs.
     * @return array|false The ordered names of columns.
     */
    public function getColumnNames();

    /**
     * This method returns the name of the schema that contains the specified
     * column.
     *
     * @exception SpicaDatabaseException If an error occurs.
     * @param  int $column The index of the column to check the schema name for.
     * @return string|false The name of the schema that contains the column.
     */
    public function getSchemaName($column);

    /**
     * This method returns the name of the table containing the specified
     * column.
     *
     * @exception SpicaDatabaseException If an error occurs.
     * @param  index The index of the column to check the table name for.
     * @return string|false The name of the table containing the column.
     */
    public function getTableName($column);
}

?>